前端项目 node 自动部署

MuYan2022-09-16web

前言

主要借助于 ssh2、scp2

  • ssh2

SSH2客户端和服务器模块是用纯JavaScript为node.js编写的。 开发/测试是在OpenSSH(目前是8.7)上完成的。

  • scp2

scp2在很大程度上受ssh2的支持,以SFTP的方式实现了SCP。

它是用纯javascript编写的,应该在每个操作系统上工作,包含Windows。需要 Nodejs (v0.8.7或更新版本)才能使其工作。

第一步:安装依赖

  • 过高版本的可能存在冲突问题,建议使用以下版本
// package.json
"devDependencies": {
  "chalk": "^4.1.2",
  "cross-env": "^7.0.3",
  "ora": "^5.1.0",
  "scp2": "^0.5.0",
  "ssh2": "^1.11.0"
}

第二步:配置 npm 命令

// package.json
"scripts": {
  "deploy:dev": "cross-env NODE_ENV=dev node ./deploy",
}

第三步:配置文件

  1. 与根目录新建 deploy 文件夹

  2. deploy 文件夹内新建 config.js 文件

    • 如果是用私钥连接服务器,则需要配置私钥文件与私钥密码
// deploy/config.js
/*
 * 定义不同环境服务器信息根据 process.env.NODE_ENV 导出当前环境服务器相关信息
 */
const SERVER_LIST = {
  // 测试服务器
  dev: {
    name: "测试环境", // 环境名称
    host: "xxx.xxx.xxx.xxx", // ip
    port: "xx", // 端口
    username: "xxxx", // 服务器登录账号名称
    password: "xxxxxxx", // 登录服务器登录密码,用私钥的话就可以注释掉,启用下面的私钥配置
    // privateKey: require("fs").readFileSync("xxxxx"), // 本地的服务器私钥文件地址,需要用绝对路径,例如: deploy/private/dev.private
    // passphrase: "xxxxx", // 服务器私钥密码
    pathPrefix: "xxxxx", // 服务器前端项目文件夹的上级地址,以 / 结尾,如: /demo/
    pathName: "xxxxx", // 服务器前端项目文件夹的名称
    path: function () {
      return `${this.pathPrefix}${this.pathName}`;
    }, // 服务器前端项目的文件夹全路径地址
  },
};

module.exports = SERVER_LIST[process.env.NODE_ENV];
  1. deploy 文件夹内新建 index.js 文件
const scpClient = require("scp2");
const ora = require("ora");
const chalk = require("chalk");
const server = require("./config");
const serverConfig = {
  host: server.host,
  port: server.port,
  username: server.username,
  password: server.password, // 用私钥就注释 password,启用下面的
//   privateKey: server.privateKey,
//   passphrase: server.passphrase,
};
const Client = require("ssh2").Client;
const conn = new Client();
// 服务器前端项目地址的上级目录地址(绝对地址)
const path = server.path();
// 备份文件夹名称,取当前时间
const currentTime = `$(date +"%Y-%m-%d~%H:%M:%S")`;
// 备份文件夹全路径(绝对地址)
const backUpUrl = `${server.pathPrefix}_backUp/${currentTime}`;
// 先判断前端项目文件夹是否存在,存在就进行备份,而后删除前端项目文件夹
const shellCmd = `if [ -d "${path}" ];then\n
echo "存在文件夹,进行拷贝"
cd ${server.pathPrefix}\n
mkdir -p ${backUpUrl}\n 
cp -r ${path}/. ${backUpUrl}/\n
rm -rf ${path}\n
else\n
echo "不存在文件夹:${path}"
fi`;

conn
  .on("ready", function () {
    console.log("====> 连接成功 <====");
    conn.exec(shellCmd, function (err, stream) {
      if (err) throw err;
      stream
        .on("close", function (code, signal) {
          console.log("====> 执行成功,关闭连接 <====");
          // 部署前端项目
          deployFile();
          // 关闭 ssh2 连接
          conn.end();
        })
        .on("data", function (data) {
          console.log("STDOUT: " + data);
        })
        .stderr.on("data", function (data) {
          console.log("STDERR: " + data);
        });
    });
  })
  .on("error", function () {})
  .connect(serverConfig);

function deployFile() {
  const spinner = ora("正在发布到" + (server.name) + "服务器...");
  spinner.start();
  scpClient.scp(
    "dist/", // 本地打包后文件(绝对路径)地址
    {
      ...serverConfig,
      path,
    },
    function (err) {
      spinner.stop();
      if (err) {
        console.log(chalk.red("发布失败.\n"));
        throw err;
      } else {
        console.log(
          chalk.green(
            "Success! 成功发布到" + (server.name) + "服务器! \n"
          )
        );
      }
    }
  );
}

第四步:配置.gitignore

服务器相关信息太过敏感,不建议上传至仓库,建议配置 .gitignore

# .gitignore
/deploy
上次更新 2026/6/23 11:49:15
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8